package cn.shop.merchant.controller.api;

import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.shop.merchant.controller.api.aes.SHA1;
import cn.shop.merchant.service.ApiService;
import cn.shop.merchant.service.MerchantUserService;
import cn.shop.transcation.merchantUser.mapper.entity.MerchantUser;
import cn.shop.utils.ApiCode;
import cn.shop.utils.ApiResult;
import cn.shop.utils.Putif;
import cn.shop.utils.exception.ServiceException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Map;

/**
 * @author : 李一涵
 * @date : Created in 2021-11-10 11:14
 * @description : 黑名单controller
 */
@Slf4j
@RestController
@RequestMapping("/open")
public class ApiController {

    @Resource
    private MerchantUserService userService;
    @Resource
    private ApiService apiService;

    private static final String TOKEN = "vB0dG2aD1dI1jE2bL2aA4kA0mO5iF2aL";

    @PostMapping("/bind")
    public ApiResult<Map<String, Object>> bindMerchantUser(@RequestBody BindReq req) {
        log.info("[api]绑定账号接口收到参数：{}", req);
        checkSignature(req.getTimestamp(), req.getNonce(), req.getSignature(), req.getAccount(), req.getPassword());
        if (StrUtil.isAllBlank(req.getAccount(), req.getPassword())) {
            return ApiResult.fail("用户名和密码不能为空");
        }
        MerchantUser user = userService.lambdaQuery()
                .eq(MerchantUser::getAccount, req.getAccount())
                .one();
        if (user == null) {
            return ApiResult.fail("用户不存在");

        }
        if (!DigestUtil.bcryptCheck(req.getPassword(), user.getPassword())) {
            return ApiResult.fail("用户名或密码不正确");
        }
        if (user.getState() != 2) {
            return ApiResult.fail("账户未启用");
        }
        String openId = DigestUtil.md5Hex(String.valueOf(user.getId()));
        boolean success = userService.lambdaUpdate().set(MerchantUser::getOpenId, openId)
                .eq(MerchantUser::getId, user.getId())
                .update();
        if (success) {
            return ApiResult.success("绑定成功", Putif.start().anyway("openId", openId).get());
        } else {
            return ApiResult.fail("绑定失败");
        }
    }

    @PostMapping("/getbalance")
    public ApiResult<Map<String, Object>> queryBalance(@RequestBody QueryBalanceReq req) {
        log.info("[api]查询余额接口收到参数：{}", req);
        checkSignature(req.getTimestamp(), req.getNonce(), req.getSignature(), req.getOpenId());
        if (StrUtil.isBlank(req.getOpenId())) {
            return ApiResult.fail("openId不能为空");
        }
        MerchantUser user = userService.lambdaQuery()
                .eq(MerchantUser::getOpenId, req.getOpenId())
                .one();
        if (user == null) {
            return ApiResult.fail("用户不存在");
        }
        return ApiResult.success(Putif.start()
                .anyway("openId", user.getOpenId())
                .anyway("balance", user.getBalance())
                .get());
    }

    @PostMapping("/recharge")
    public ApiResult<Map<String, Object>> charge(@RequestBody ChargeReq req) {
        log.info("[api]账户充值接口收到参数：{}", req);
        checkSignature(req.getTimestamp(), req.getNonce(), req.getSignature(), req.getOpenId(), req.getAmount(), req.getChannel());
        if (StrUtil.isBlank(req.getOpenId())) {
            return ApiResult.fail("openId不能为空");
        }
        MerchantUser user = userService.lambdaQuery()
                .eq(MerchantUser::getOpenId, req.getOpenId())
                .one();
        if (user == null) {
            return ApiResult.fail("用户不存在");
        }
        if (StrUtil.isBlank(req.getAmount()) || !NumberUtil.isNumber(req.getAmount())) {
            return ApiResult.fail("请检查充值金额");
        }
        BigDecimal amount = new BigDecimal(req.getAmount());
        if (amount.equals(BigDecimal.ZERO)) {
            return ApiResult.fail("充值金额需大于0元");
        }
        if (StrUtil.isBlank(req.getChannel())) {
            return ApiResult.fail("充值渠道不能为空");
        }
        return ApiResult.result(apiService.recharge(user, amount, req.getChannel()));
    }

    private void checkSignature(String timestamp, String nonce, String signature, String... params) {
        String msgSign = "";
        try {
            msgSign = SHA1.getSHA1(TOKEN, timestamp, nonce, params);
        } catch (Exception e) {
            log.warn("获取加密串失败", e);
            throw new ServiceException(ApiCode.COMPUTE_SIGNATURE_ERROR.description(), ApiCode.COMPUTE_SIGNATURE_ERROR);
        }
        if (StrUtil.isBlank(signature) || StrUtil.equals(msgSign, signature)) {
            throw new ServiceException(ApiCode.VALIDATE_SIGNATURE_ERROR.description(), ApiCode.VALIDATE_SIGNATURE_ERROR);
        }
    }

}
